' BASIC Anywhere Machine program by Charlie Veniot
' Based on 2 Gears Turning mod b+ 2023-02-25 (https://friends-of-basic.freeforums.net/thread/197/2-gears-turning-smallbasic)

'🟠 Settings & Initialisation
  SCREEN _NEWIMAGE(450, 200, 23 )
  DIM AS DOUBLE a, ao
  x_move = -50 : y_move = -125 : max_height = 70
  zmax = 1
  zmax_inc = 2
  
'🟠 Main
  DO 
    GOSUB Loop_FirstStuff
    For z = 0 TO zmax
      FOR a = 0 TO _PI(2) STEP .00275
        Set_x1_y1: r = [100] + [COS(20*a)*15]
            x1 = INT([220] + [COS(a+ao)*r])
            y1 = INT([240] + [SIN(a+ao)*r/3] - [z/2])
        Set_x2_y2: r = [50] + [SIN(-10*a)*15]
            x2 = INT([390] + [COS(a-2*ao)*r]) 
            y2 = INT([240] + [SIN(a-2*ao)*r/3] - [z/2])
        cb = INT([z*200/max_height] + [55])
        IF z < zmax THEN _
            PSET ([x1+x_move],[y1+y_move]), _
                 _RGB( [INT(cb*bb_red)] , [INT(cb*bb_green)] , [INT(cb*bb_blue)] ) : _
            PSET ([x2+x_move],[y2+y_move]), _
                 _RGB( [INT(cb*lb_red)] , [INT(cb*lb_green)] , [INT(cb*lb_blue)] )
        IF z = zmax THEN _
            LINE ([220+x_move],[{240+y_move}-{z/2}]) - ([x1+x_move],  [y1+y_move]), _
                _RGB( [INT(256*bb_red)] , [INT(256*bb_green)] , [INT(256*bb_blue)] ) : _
            LINE ([220+x_move],[{240+y_move}-{z/2}]) - ([x1-1+x_move],[y1+y_move]), _
                _RGB( [INT(256*bb_red)] , [INT(256*bb_green)] , [INT(256*bb_blue)] ): _
            LINE ([390+x_move],[{240+y_move}-{z/2}]) - ([x2+x_move],  [y2+y_move]), _
                _RGB( [INT(256*lb_red)] , [INT(256*lb_green)] , [INT(256*lb_blue)] ) : _
            LINE ([390+x_move],[{240+y_move}-{z/2}]) - ([x2-1+x_move],[y2+y_move]), _
                _RGB( [INT(256*lb_red)] , [INT(256*lb_green)] , [INT(256*lb_blue)] )
      NEXT a
    NEXT z
    GOSUB Loop_LastStuff
  LOOP

'🟠 Subroutines

Loop_FirstStuff:  
    CLS
    IF zmax < 1 THEN zmax = 1
    IF zmax = 1 THEN _
        bb_red = rnd : bb_green = rnd : bb_blue = rnd : _
        lb_red = rnd : lb_green = rnd : lb_blue = rnd
RETURN

Loop_LastStuff:  
    _DELAY 0.005 / ( zmax ^ 2 )
    ao = ao + .1
    IF INT(ao * 10) MOD 2 = 0 THEN zmax += zmax_inc
    IF zmax > max_height THEN zmax_inc = - zmax_inc : zmax = max_height
    IF zmax = 1 AND ao > .1 THEN zmax_inc = - zmax_inc
RETURN